import Bullet, { BulletState } from "../../bullet";
import { BulletSide } from "../../physics_math";
import CharacterArmature from "./character_armature";
import CharacterCtrl from "./character_ctrl";


export class DamageType {
    key = "";
    value = 0;
};
const { ccclass, property } = cc._decorator;

//普通行走
//复杂地形行走（多个方块拼接，接缝）
//载具
//薄膜
//单向墙
//过滤

//攀岩
//攀岩跳跃
//游泳
//无重力控制
//

@ccclass
export default class Character extends Bullet {
    stun = 0;
    jumpStun = 0;
    //拿在手上的
    grabedBullet: Bullet = null;
    //正在使用的
    usedBullet: Bullet = null;
    ctrl: CharacterCtrl = null;
    grabedBulletPosOffset = cc.v2();

    @property(cc.Label)
    lbPlayerName: cc.Label = null;
    @property(CharacterArmature)
    arm: CharacterArmature = null;

    protected onDestroy(): void {
        if (cc.isValid(this.grabedBullet)) {
            this.drop();
        }
        super.onDestroy && super.onDestroy();
    }
    onDockCountChanged(): void {
    }
    updateGrabedBullet() {
        if (cc.isValid(this.grabedBullet)) {
            switch (this.vLookAt) {
                case BulletSide.Top:
                    this.grabedBulletPosOffset = cc.v2(0, 75);
                    break;
                case BulletSide.Bottom:
                    this.grabedBulletPosOffset = cc.v2(0, -75);
                    break;
                case BulletSide.None:
                    switch (this.hLookAt) {
                        case BulletSide.Left:
                            this.grabedBulletPosOffset = cc.v2(-75, 0);
                            break;
                        case BulletSide.Right:
                            this.grabedBulletPosOffset = cc.v2(75, 0);
                            break;
                    }
                    break;
            }
            this.grabedBullet.curPos = this.curPos.add(this.grabedBulletPosOffset);
        }
    }

    onLookAtChanged(h: BulletSide, v: BulletSide): void {
        if (cc.isValid(this.grabedBullet)) {
            this.grabedBullet.hLookAt = h;
            this.grabedBullet.hLookAt = v;
        }
        switch (h) {
            case BulletSide.Left:
                this.arm.isFilp = false;
                break;
            case BulletSide.Right:
                this.arm.isFilp = true;
                break;
        }
        switch (v) {
            case BulletSide.None:
                this.arm.play("state-look-ahead", "head");
                break;
            case BulletSide.Top:
                this.arm.play("state-look-up", "head");
                break;
            case BulletSide.Bottom:
                this.arm.play("state-look-down", "head");
                break;
        }
    }
    damage(dam: DamageType): void {
        switch (dam.key) {
            case "FireBall":
            case "ElectronBall":
                this.blowup();
                break;
            case "WaterBall":
                break;
        }
    }
    move(v2: cc.Vec2) {
        this.applyForce(v2);
    }
    idle() {
    }
    jump(power: number) {
        if (this.float <= 0) {
            if (this.dockCount[BulletSide.Bottom - 1] <= 0) {
                console.warn("没站稳，不能跳起");
                return;
            }
        }
        if (this.jumpStun > 0) {
            return;
        }
        this.applyForce(cc.v2(0, power));
        this.jumpStun += 0.2;

        this.arm.pacShot();
    }
    drop() {
        if (this.stun > 0) {
            return;
        }
        if (!cc.isValid(this.grabedBullet)) {
            return;
        }
        let throwPower = this.speed.clone();
        switch (this.hLookAt) {
            case BulletSide.Left:
                throwPower = throwPower.add(cc.v2(-800, 0));
                break;
            case BulletSide.Right:
                throwPower = throwPower.add(cc.v2(800, 0));
                break;
        }

        switch (this.vLookAt) {
            case BulletSide.Top:
                throwPower = throwPower.add(cc.v2(0, 400));
                break;
            case BulletSide.Bottom:
                throwPower = throwPower.add(cc.v2(0, 0));
                break;
        }

        this.grabedBullet.applyForce(this.speed.add(throwPower));
        this.grabedBullet.dropBy(this);

        this.grabedBullet.off(this);
        this.grabedBullet = null;
    }
    grab() {
        if (this.stun > 0) {
            return;
        }
        if (cc.isValid(this.grabedBullet)) {
            return;
        }

        let loc = this.node.convertToWorldSpaceAR(cc.Vec2.ZERO);
        switch (this.hLookAt) {
            // case BulletSide.Top:
            //     loc.y += 75;
            //     break;
            // case BulletSide.Bottom:
            //     loc.y += -75;
            //     break;
            case BulletSide.Left:
                loc.x += -75;
                break;
            case BulletSide.Right:
                loc.x += 75;
                break;
        }
        let hotBox = cc.rect(loc.x, loc.y, 100, 80);

        let list = this.world.getComponentsInChildren(Bullet);

        for (let i = 0; i < list.length; i++) {
            let bullet = list[i];
            if (bullet === this) {
                continue;
            }

            if (!bullet.isGrabable) {
                continue;
            }

            if (bullet.state === BulletState.Grabed) {
                continue;
            }

            if (cc.Intersection.rectRect(hotBox, bullet.node.getBoundingBoxToWorld())) {
                //拿取对象
                this.grabedBullet = bullet;
                this.grabedBullet.on("destroy", this.onGrabDestroy, this);
                this.grabedBullet.grabBy(this);
                break;
            }
        }
    }
    onGrabDestroy() {
        this.grabedBullet = null;
    }
    unuse() {
        if (cc.isValid(this.usedBullet)) {
            this.usedBullet.unuseBy(this);
            this.usedBullet.off(this);
        }
        this.usedBullet = null;
    }
    use() {
        if (this.stun > 0) {
            return;
        }
        let useTarget: Bullet = null;
        //查看是否有拿取
        if (this.grabedBullet && this.grabedBullet.isUseable) {
            useTarget = this.grabedBullet;
        }
        else {
            let loc = this.node.convertToWorldSpaceAR(cc.v2(25, -40));
            let hotBox = cc.rect(loc.x, loc.y, 100, 80);
            let list = this.world.getComponentsInChildren(Bullet);

            for (let i = 0; i < list.length; i++) {
                let bullet = list[i];
                // if (bullet.isSensor) {
                //     continue;
                // }
                if (bullet === this) {
                    continue;
                }
                if (!bullet.isUseable) {
                    continue;
                }

                if (cc.Intersection.rectRect(hotBox, bullet.node.getBoundingBoxToWorld())) {
                    //使用对象
                    useTarget = bullet;
                    break;
                }
            }
        }
        if (useTarget) {
            this.stun += 0.25;
            useTarget.useBy(this);
            this.usedBullet = useTarget;
            useTarget.on("destroy", this.onUsedBulletDestroy, this);
        }
    }
    onUsedBulletDestroy() {
        this.usedBullet = null;
    }

    onEnterStand(): void {
        // Sound2D.Play(this.node, `step${Random.range(1, 4)}`);
        if (this.speed.y < -3500) {
            this.blowup();
        }
    }

    blowup() {
        this.emit("blowup", this);
        this.node.destroy();
    }

    onPhysicsUpdate(dt: number) {
        this.updateGrabedBullet();
    }
    protected lateUpdate(dt: number): void {
        if (this.jumpStun > 0) {
            this.jumpStun -= dt;
        }

        if (this.dockCount[BulletSide.Bottom - 1] <= 0) {
            if (this.speed.y > 0) {
                this.arm.play("float-up");
            }
            else if (this.speed.y < 0) {
                this.arm.play("float-down");
            }
            else {

                this.arm.play("float-ahead");
            }
        }
        else {
            //todo: push动作需要做一个 this.pushSide 来记录。因为 push时候this.speed.x == 0 ，所以不能判断。
            // if (this.dockCount[BulletSide.Left - 1] > 0 && this.speed.x < 0) {
            //     this.arm.play("push");
            // }
            // else if (this.dockCount[BulletSide.Right - 1] > 0 && this.speed.x > 0) {
            //     this.arm.play("push");
            // }
            if(0){}
            else {
                let idleMaxX = 55;
                if (this.speed.x > idleMaxX) {
                    if (this.hLookAt === BulletSide.Right) {
                        this.arm.play("run");
                    }
                    else {
                        this.arm.play("breaking");
                    }
                }
                else if (this.speed.x < -idleMaxX) {
                    if (this.hLookAt === BulletSide.Left) {
                        this.arm.play("run");
                    }
                    else {
                        this.arm.play("breaking");
                    }
                }
                else {
                    this.arm.play("idle");
                }
            }
        }
    }
};